package com.itlong.cloud.app.service.impl;

import com.alibaba.fastjson.JSON;
import com.itlong.cloud.POJO.DTO.app.AppMonthCarBillDTO;
import com.itlong.cloud.POJO.DTO.app.AppMonthCardFeeRecordPageDTO;
import com.itlong.cloud.POJO.PO.PropertyCardPaymentRecordPO;
import com.itlong.cloud.POJO.PO.PropertyPaymentBillPO;
import com.itlong.cloud.POJO.VO.app.AppMonthCardBillVO;
import com.itlong.cloud.POJO.VO.app.AppMonthCardFeeRecordVO;
import com.itlong.cloud.POJO.VO.app.AppMonthCardParkingVO;
import com.itlong.cloud.POJO.VO.miniprogram.WeChatOfficialGetMonthCardCarVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.app.dao.IAppMonthCardParkingDao;
import com.itlong.cloud.app.service.IAppMonthCardParkingService;
import com.itlong.cloud.constants.RabbitMQConstant;
import com.itlong.cloud.constants.RedisConstant;
import com.itlong.cloud.enumerate.DataStatusEnum;
import com.itlong.cloud.property.dao.IPropertyPaymentManageDao;
import com.itlong.cloud.rabbitmq.config.MessageSender;
import com.itlong.cloud.service.RedisService;
import com.itlong.cloud.utils.data.handler.SqlUtil;
import com.itlong.cloud.utils.date.DateUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.random.LogicIdUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <desc>
 *      APP-月卡停车模块接口实现类.
 * </desc>
 *
 * @createDate 2018/11/6
 */
@Service
public class AppMonthCardParkingServiceImpl implements IAppMonthCardParkingService {

    @Autowired
    IAppMonthCardParkingDao iAppMonthCardParkingDao;

    @Autowired
    IPropertyPaymentManageDao iPropertyPaymentManageDao;

    @Autowired
    RedisService redisService;

    @Autowired
    private MessageSender messageSender;

    /**
     * <desc>
     *      获取月卡车辆列表
     * </desc>
     *
     * @param userId
     * @return 车辆列表信息
     * @author Juguang.S
     * @createDate 2018/11/06
     */
    @Override
    public List<AppMonthCardParkingVO> getMonthCarList(String userId) throws Exception {
        //判断当前用户是否为租客，若为租客则只需要查绑定车辆时车主手机号相同的车辆
        SimpleDateFormat sDateFormat=new SimpleDateFormat("yyyy-MM-dd");
        String phoneNum = iAppMonthCardParkingDao.isUserTenant(userId);
        List<AppMonthCardParkingVO> returnList = new ArrayList<>();
        List<AppMonthCardParkingVO> list = null;
        if(StringUtils.isNotEmpty(phoneNum)){
            list = iAppMonthCardParkingDao.getMonthCarListTenant(phoneNum);
            if(list != null ){
                for(AppMonthCardParkingVO parkingVO : list){
                    if(parkingVO.getLfitDay().startsWith("-")){
                        parkingVO.setLfitDay("0");
                    }
                    if(StringUtils.isNotEmpty(parkingVO.getEndDateCon())){
                        Date endDate = sDateFormat.parse(parkingVO.getEndDateCon());
                        if((new Date()).getTime()>endDate.getTime()){
                            parkingVO.setEndDate("");
                        }
                    }
                }
            }
            return list;
        }else{
            list = iAppMonthCardParkingDao.getMonthCarList(userId);
            if(list != null){
                for(AppMonthCardParkingVO parkingVO : list){
                    if(parkingVO.getLfitDay().startsWith("-")){
                        parkingVO.setLfitDay("0");
                    }
                    if(StringUtils.isNotEmpty(parkingVO.getEndDateCon())){
                        Date endDate = sDateFormat.parse(parkingVO.getEndDateCon());
                        if((new Date()).getTime()>endDate.getTime()){
                            parkingVO.setEndDate("");
                        }
                    }
                    //确认该车辆是否是租客所属车辆
                    if(iAppMonthCardParkingDao.getParkIsTenant(parkingVO.getCarId(),userId)==0){
                        returnList.add(parkingVO);
                    }
                }
            }
            return returnList;
        }
    }

    /**
     * <desc>
     *      获取当前用户是否是月卡用户
     * </desc>
     *
     * @param userId
     * @return
     * @author Juguang.S
     * @createDate 2018/11/06
     */
    @Override
    public Integer getUserIsParkVIP(String userId) throws Exception {
        Integer count = iAppMonthCardParkingDao.getUserIsParkVIP(userId);
        List<AppMonthCardParkingVO> list = iAppMonthCardParkingDao.getMonthCarList(userId);
        if(count>0 && list !=null && !list.isEmpty()){
            return 1;
        }
        return 0;
    }

    /**
     * <desc>
     *      生成月卡车辆缴费账单
     * </desc>
     *
     * @param  appMonthCarBillDTO 生成账单所需参数
     * @return 缴费账单信息数据
     * @author Juguang.S
     * @createDate 2018/11/07
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public AppMonthCardBillVO monCarFeeBill(AppMonthCarBillDTO appMonthCarBillDTO) throws Exception {
        //根据项目编号和车牌号查询APP账单展示所需的数据
        AppMonthCardBillVO appMonthCardBillVO = iAppMonthCardParkingDao.getAppMonCarFeeBill(appMonthCarBillDTO.getCarId(),appMonthCarBillDTO.getProjectId());
        //处理生成账单的逻辑
        PropertyPaymentBillPO billPO = new PropertyPaymentBillPO();
        if(StringUtils.isEmpty(appMonthCarBillDTO.getMonth())){
            //生成费用单号 规则年月日+六位流水号，如180720000001
            String date = DateUtil.fomatDate(new Date(), "yyMMdd");
            //从缓存中获取流水号
            String redisKey = RedisConstant.REDIS_PAYMENT_BILL_SERIAL_NUMBER_CACHE+appMonthCarBillDTO.getProjectId()+date;
            Integer tradeNo = (Integer)redisService.getObject(redisKey, Integer.class);
            if(tradeNo == null){
                //查询数据库中是否有当前流水号，有的话将当前流水号放入缓存中且+1赋值给tradeNo
                String feeNumber = iPropertyPaymentManageDao.getFeeNumberByDate(DateUtil.fomatDate(new Date(), "yyyy-MM-dd"),appMonthCarBillDTO.getProjectId());
                if(StringUtils.isBlank(feeNumber)){
                    tradeNo = 1;
                }else{
                    tradeNo = Integer.valueOf(feeNumber);
                    tradeNo += 1;
                }
            }else{
                tradeNo+=1;
            }
            redisService.set(redisKey,RedisConstant.REDIS_PAYMENT_BILL_SERIAL_NUMBER_CACHE_TIME,tradeNo);
            billPO.setFeeNumber(date+ StringHandlerUtil.autlSupply(6,tradeNo.toString(),"0"));
            billPO.setFeeId(LogicIdUtil.bussinessId());
            billPO.setType(3);
            billPO.setProjectId(appMonthCarBillDTO.getProjectId());
            billPO.setFeeStatus(1);
            billPO.setStatus(DataStatusEnum.NORMAL.getType());
            billPO.setCreateTime(new Date());
            billPO.setCarId(appMonthCarBillDTO.getCarId());
            billPO.setMonthCardId(appMonthCardBillVO.getMonthCardId());
            iAppMonthCardParkingDao.save(SqlUtil.durableData(billPO, PlatformConstants.TABLE_SAVE));
            appMonthCardBillVO.setBillId(billPO.getFeeId());
            //判断当前月卡车是否已过期，已过期则不显示
            if(StringUtils.isNotEmpty(appMonthCardBillVO.getEndDate())){
                if(DateUtil.fomatLongDate2(appMonthCardBillVO.getEndDate()).compareTo(DateUtil.fomatLongDate2(DateUtil.fomatDate(new Date(), "yyyy-MM-dd")))<0){
                    appMonthCardBillVO.setEndDate("");
                }
            }
        }else{
            //根据月数算出金额并更新账单
            billPO.setFeeId(appMonthCarBillDTO.getBillId());
            BigDecimal amount = new BigDecimal(appMonthCardBillVO.getFeeStandard()).multiply(new BigDecimal(appMonthCarBillDTO.getMonth()));
            billPO.setDueAmount(amount);
            billPO.setPaidAmount(amount);
            billPO.setUpdateTime(new Date());
            billPO.setMonth(appMonthCarBillDTO.getMonth());
            iAppMonthCardParkingDao.update(SqlUtil.durableData(billPO,PlatformConstants.TABLE_UPDATE));
            appMonthCardBillVO.setMonth(appMonthCarBillDTO.getMonth());
            appMonthCardBillVO.setPrice(amount.toString());
            appMonthCardBillVO.setBillId(appMonthCarBillDTO.getBillId());
        }

        return appMonthCardBillVO;
    }

    /**
     * <desc>
     *      保存月卡缴费记录
     * </desc>
     *
     * @param  recordPO 保存数据
     * @return
     * @author Juguang.S
     * @createDate 2018/11/08
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public Integer saveMonthCardFeeRecord(PropertyCardPaymentRecordPO recordPO) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar rightNow = Calendar.getInstance();
        recordPO.setStatus(DataStatusEnum.NORMAL.getType());
        recordPO.setCreateTime(new Date());
        //获取此时月卡有效期的截止日期并计算出续费后的截止日期
        String endTime = iAppMonthCardParkingDao.getMonthCarEndTime(recordPO.getCarId());
        //如果截止时间为空则开始时间从当日算起
        if(StringUtils.isEmpty(endTime)){
            recordPO.setStartTime(new Date());
            rightNow.setTime(new Date());
        }else{
            recordPO.setStartTime(sdf.parse(endTime));
            rightNow.setTime(sdf.parse(endTime));
        }
        rightNow.add(Calendar.MONTH, recordPO.getMonth());
        Date dt1 = rightNow.getTime();
        String reStr = sdf.format(dt1);
        recordPO.setEndTime(sdf.parse(reStr));
        return iAppMonthCardParkingDao.save(SqlUtil.durableData(recordPO,PlatformConstants.TABLE_SAVE));
    }

    /**
     * <desc>
     *      获取当前用户下月卡车辆缴费账单列表
     * </desc>
     *
     * @param recordPageDTO 获取账单所需参数
     * @return 缴费记录
     * @author Juguang.S
     * @createDate 2018/11/08
     */
    @Override
    public List<AppMonthCardFeeRecordVO> getMonPayListPage(AppMonthCardFeeRecordPageDTO recordPageDTO) throws Exception {
        //将DTO转换为Map
        Map<String,Object> params = SqlUtil.convertBeanToMapParams(recordPageDTO);
        //分页默认pageSize为20
        Page<AppMonthCardFeeRecordVO> page = new Page<>();
        page.getPage().setPageSize(recordPageDTO.getPageSize());
        page.getPage().setCurrentPage(recordPageDTO.getPageNum());
        params.put("currentPage",page.getPage().getStartSlip());
        params.put("pageSize",page.getPage().getPageSize());

        //判断当前用户是否为租客，若为租客则只需要查绑定车辆时车主手机号相同的车辆
        String phoneNum = iAppMonthCardParkingDao.isUserTenant(recordPageDTO.getUserId());
        List<AppMonthCardFeeRecordVO> returnList = new ArrayList<>();
        if(StringUtils.isNotEmpty(phoneNum)){
            params.put("phoneNum",phoneNum);
            return iAppMonthCardParkingDao.getMonthCarPayInfoTenant(params);
        }else{
            List<AppMonthCardFeeRecordVO> list = iAppMonthCardParkingDao.getMonPayListPage(params);
            if(list != null){
                for(AppMonthCardFeeRecordVO parkingVO : list){
                    //确认该车辆是否是租客所属车辆
                    if(iAppMonthCardParkingDao.getParkIsTenant(parkingVO.getCarId(),recordPageDTO.getUserId())==0){
                        returnList.add(parkingVO);
                    }
                }
                return returnList;
            }
            return list;
        }
    }

    /**
     * <desc>
     *      处理零元支付情况
     * </desc>
     *
     * @param billId 账单ID
     * @return 缴费记录
     * @author Juguang.S
     * @createDate 2018/11/15
     */
    @Override
    public void noticeZeroPayment(String billId) throws Exception {
        Map<String,Object> params=new HashMap<>();
        params.put("feeId", billId);
        params.put("account", "0");
        params.put("projectId", "");
        params.put("transactionId","");
        params.put("tradeId","");
        params.put("realTotal","0");

        messageSender.send(RabbitMQConstant.RABBITMQ_PARKING_BILL_PEY_MANAGER_QUEUE, JSON.toJSONString(params),
                RabbitMQConstant.RABBITMQ_PROJECT_EXCHANGE,
                RabbitMQConstant.RABBITMQ_PARKING_BILL_PEY_ROUTING_KEY);
    }

    /**
     * <desc>
     *      微信公众号获取月卡车辆列表
     * </desc>
     *
     * @return 月卡车辆列表
     * @author wangzhi
     * @createDate 2019/04/01
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<WeChatOfficialGetMonthCardCarVO> getMonthCardCarList(String plateNumber) throws Exception {
        return iAppMonthCardParkingDao.getMonthCardCarList(plateNumber);
    }
}